package com.mxy.myapplication.service;

import android.app.Activity;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
import android.os.Message;
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationCompat;
import android.view.View;
import android.widget.RemoteViews;

import com.mxy.myapplication.R;
import com.mxy.myapplication.activity.MainActivity;
import com.mxy.myapplication.util.Util;

import java.lang.ref.WeakReference;

/**
 * 常驻服务+仿网易云音乐通知栏操作效果
 * 通知栏自定义样式，控件点击+动态变更效果
 * 一堆比你粗名还比你勤奋的人在前面跑，不学习还怎么混?
 *
 * @author 马晓勇
 */
public class MyService extends Service {

    private NotificationCompat.Builder notificationBuilder;
    private Notification notice;
    private RemoteViews smallremoteView;
    private RemoteViews bigRemoteViews;
    private NotificationReceiver notificationReceiver;
    private NotificationManager notificationManager;
    private static final int NOTICEID = 121444;

    /**
     * 当前播放第几首歌曲
     */
    private int nowsong = 1;
    private MyBinder binder;
    private static final String NOTIFICATION_CHANNEL_ID = "1";
    private static final String NOTIFICATION_CHANNEL_NAME = "foregroundNotificationChannel";

    @Override
    public void onCreate() {
        System.out.println("MyService onCreate");
        super.onCreate();
        notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        //通知栏
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("play");
        intentFilter.addAction("pouse");
        intentFilter.addAction("lastsong");
        intentFilter.addAction("nextsong");
        intentFilter.addAction("follow");
        intentFilter.addAction("close");
        notificationReceiver = new NotificationReceiver();
        this.registerReceiver(notificationReceiver, intentFilter);
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        System.out.println("onStartCommand");
        preNotification();
        //重投递intent,当service被kill后，会重启service,重新传递intent
        //START_STICKY 也会重启service但是intent会传入null
        return Service.START_REDELIVER_INTENT;
    }

    @Override
    public void onDestroy() {
        System.out.println("MyService onDestroy");
        this.stopForeground(true);
        this.unregisterReceiver(notificationReceiver);
        super.onDestroy();
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        System.out.println("MyService   onBind");
        Message message = MainActivity.getMessage(3);
        message.sendToTarget();
        preNotification();
        binder = new MyBinder(this);
        return binder;
    }

    @Override
    public boolean onUnbind(Intent intent) {
        System.out.println("MyService   onUnbind");
        return super.onUnbind(intent);
    }

    /**
     * 准备启动通知栏
     * <p>
     * <p>
     * Android 8.0 新的重要特性：NotificationChannel 用于桌面图标提示，长安弹出消息内容
     * （1）创建NotificationChannel
     * <p>
     * 如果你需要发送属于某个自定义渠道的通知，你需要在发送通知前创建自定义通知渠道，示例如下：
     * <p>
     * //ChannelId为"1",ChannelName为"Channel1"
     * NotificationChannel channel = new NotificationChannel("1","Channel1", NotificationManager
     * .IMPORTANCE_DEFAULT);
     * channel.setLightColor(Color.BLUE); //应用图标提示点颜色
     * channel.setShowBadge(true); //是否在久按桌面图标时显示此渠道的通知
     * channel.enableLights(true); //是否允许控制手机通知灯
     * channel.enableVibration(true);//是否允许震动
     * notificationManager.createNotificationChannel(channel);
     * <p>
     * （2）向NotificationChannel发送通知
     * <p>
     * public static void showChannel1Notification(Context context) {
     * int notificationId = 0x1234;
     * Notification.Builder builder = new Notification.Builder(context,"1"); //与channelId对应
     * //icon title text必须包含，不然影响桌面图标小红点的展示
     * builder.setSmallIcon(android.R.drawable.stat_notify_chat)
     * .setContentTitle("xxx")
     * .setContentText("xxx")
     * .setNumber(3); //久按桌面图标时允许的此条通知的数量
     * NotificationManager notificationManager = (NotificationManager) context.getSystemService
     * (Context.NOTIFICATION_SERVICE);
     * notificationManager.notify(notificationId, builder.build());
     * }
     * <p>
     * （3）删除NotificationChannel
     * notificationManager.deleteNotificationChannel(NOTIFICATION_CHANNEL_ID);
     */
    private void preNotification() {
        synchronized (MyService.this) {
            //避免重复创建通知
            if (this.notificationBuilder == null) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    NotificationChannel notificationChannel = createNotificationChannel(false);
                    if (notificationChannel != null) {
                        this.notificationBuilder = new NotificationCompat.Builder(this,
                                notificationChannel.getId());
                    } else {
                        this.notificationBuilder = new NotificationCompat.Builder(this);
                    }
                } else {
                    this.notificationBuilder = new NotificationCompat.Builder(this);
                }

                this.startForeground(NOTICEID, getNotification());
            }
        }
    }

    /**
     * 创建NotificationChannel
     * <p>
     * 在Android 8.0以上版本中，桌面图标可以在有消息通知时出现一个小红点，用户可以长安图标，弹出消息提示
     *
     * @param importance 消息级别  true:高级(通知灯+震动+提示音)  false:低级(不打扰)
     */
    private NotificationChannel createNotificationChannel(boolean importance) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID,
                    NOTIFICATION_CHANNEL_NAME, importance ? NotificationManager.IMPORTANCE_HIGH :
                    NotificationManager.IMPORTANCE_LOW);
            //应用图标提示点颜色
            channel.setLightColor(Color.BLUE);
            //是否在久按桌面图标时显示此渠道的通知
            channel.setShowBadge(true);
            //是否允许震动
            channel.enableVibration(true);
            //是否允许控制手机通知灯
            channel.enableLights(true);
            notificationManager.createNotificationChannel(channel);
            return channel;
        } else {
            return null;
        }
    }

    /**
     * 自定义通知栏常编辑
     *
     * @return
     */
    private Notification getNotification() {

        //android 6.0以上，SmallIcon需要使用白色图标，否则android会把不透明的部分全部绘制成白色
        notificationBuilder.setSmallIcon(R.drawable.notificationlogomusic);
//        notificationBuilder.setTicker("动漫之家");//状态栏消息滚动说明
        notificationBuilder.setContentTitle("动漫之家");
        notificationBuilder.setContentText("动漫之家正在运行");
        //时间
        notificationBuilder.setWhen(System.currentTimeMillis());
//        Bitmap bitmap= BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher);
//        notificationBuilder.setLargeIcon(bitmap);

        //设置带进度条的通知栏 前提是使用默认通知栏布局
        //第三个参数为设置进度条样式,true : 不确定式进度条，false : 精确自增式进度条
        //notificationBuilder.setProgress(100,10,false);

        //5.0以上横幅消息推送
        //情况1:设置消息优先级 从Android 5.0开始，如果notification  priority设置为HIGH, MAX,
        // 并且设置了notificationbuilder.setDefaults(NotificationCompat.DEFAULT_ALL)
        //情况2:设置setfullscreenintent();
        //声音+震动+呼吸灯
        //notificationBuilder.setDefaults(NotificationCompat.DEFAULT_ALL);
        notificationBuilder.setPriority(NotificationCompat.PRIORITY_MAX);

        //设置点击后不取消
//        notificationBuilder.setAutoCancel(false);
        //设置为前台常驻服务通知 setAutoCancel和setOngoing调用一个即可
        notificationBuilder.setOngoing(true);

        notificationBuilder.setCustomContentView(getSmallRemoteView());
        notificationBuilder.setCustomBigContentView(getBigRemoteViews());
        /**
         设置可见性

         您的应用可以控制在安全锁定屏幕上显示的通知中可见的详细级别。 调用 setVisibility() 并指定以下值之一：

         VISIBILITY_PUBLIC 显示通知的完整内容。
         VISIBILITY_SECRET 不会在锁定屏幕上显示此通知的任何部分。
         VISIBILITY_PRIVATE 显示通知图标和内容标题等基本信息，但是隐藏通知的完整内容。
         设置 VISIBILITY_PRIVATE 后，您还可以提供其中隐藏了某些详细信息的替换版本通知内容。
         例如，短信 应用可能会显示一条通知，指出“您有 3 条新短信”，但是隐藏了短信内容和发件人。
         要提供此替换版本的通知，请先使用 NotificationCompat.Builder 创建替换通知。创建专用通知对象时，请通过 setPublicVersion()
         方法为其附加替换通知。
         **/
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            //5.0系统以上，锁屏界面显示
            notificationBuilder.setVisibility(Notification.VISIBILITY_PUBLIC);
        }
        notificationBuilder.setContentIntent(notificationClick());
        notice = notificationBuilder.build();
        return notice;
    }

    /**
     * @return 返回高度64dp标准通知栏样式
     */
    private RemoteViews getSmallRemoteView() {

        smallremoteView = new RemoteViews(getPackageName(),
                (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) ?
                        R.layout.notification_small_layout_api24 :
                        R.layout.notification_small_layout);
        //Android4.X
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            smallremoteView.setTextColor(R.id.songname, Color.WHITE);
        }
        smallremoteView.setTextViewText(R.id.songname, "豆豆龙");
        smallremoteView.setTextViewText(R.id.songer, "范晓萱");
        smallremoteView.setImageViewResource(R.id.songlogo, R.drawable.lm);

        smallremoteView.setOnClickPendingIntent(R.id.play,
                PendingIntent.getBroadcast(this.getApplicationContext(), 1002, new Intent("play")
                        , PendingIntent.FLAG_UPDATE_CURRENT));
        smallremoteView.setOnClickPendingIntent(R.id.pouse,
                PendingIntent.getBroadcast(this.getApplicationContext(), 1003,
                        new Intent("pouse"), PendingIntent.FLAG_UPDATE_CURRENT));
        smallremoteView.setOnClickPendingIntent(R.id.nextsong,
                PendingIntent.getBroadcast(this.getApplicationContext(), 1004, new Intent(
                        "nextsong"), PendingIntent.FLAG_UPDATE_CURRENT));
        smallremoteView.setOnClickPendingIntent(R.id.follow,
                PendingIntent.getBroadcast(this.getApplicationContext(), 1005, new Intent("follow"
                ), PendingIntent.FLAG_UPDATE_CURRENT));
        smallremoteView.setOnClickPendingIntent(R.id.close,
                PendingIntent.getBroadcast(this.getApplicationContext(), 1006,
                        new Intent("close"), PendingIntent.FLAG_UPDATE_CURRENT));
        return smallremoteView;
    }

    /**
     * @return 返回高度大于64dp的自定义通知栏样式
     */
    private RemoteViews getBigRemoteViews() {

        bigRemoteViews = new RemoteViews(getPackageName(), R.layout.notification_big_layout);
        //Android4.X
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            bigRemoteViews.setTextColor(R.id.songname, Color.WHITE);
            bigRemoteViews.setViewVisibility(R.id.line, View.INVISIBLE);
        }
        bigRemoteViews.setTextViewText(R.id.songname, "豆豆龙");
        bigRemoteViews.setTextViewText(R.id.songer, "范晓萱");
        bigRemoteViews.setImageViewResource(R.id.songlogo, R.drawable.lm);

        bigRemoteViews.setOnClickPendingIntent(R.id.play,
                PendingIntent.getBroadcast(this.getApplicationContext(), 1007, new Intent("play")
                        , PendingIntent.FLAG_UPDATE_CURRENT));
        bigRemoteViews.setOnClickPendingIntent(R.id.pouse,
                PendingIntent.getBroadcast(this.getApplicationContext(), 1008,
                        new Intent("pouse"), PendingIntent.FLAG_UPDATE_CURRENT));
        bigRemoteViews.setOnClickPendingIntent(R.id.lastsong,
                PendingIntent.getBroadcast(this.getApplicationContext(), 1009, new Intent(
                        "lastsong"), PendingIntent.FLAG_UPDATE_CURRENT));
        bigRemoteViews.setOnClickPendingIntent(R.id.nextsong,
                PendingIntent.getBroadcast(this.getApplicationContext(), 1010, new Intent(
                        "nextsong"), PendingIntent.FLAG_UPDATE_CURRENT));
        bigRemoteViews.setOnClickPendingIntent(R.id.follow,
                PendingIntent.getBroadcast(this.getApplicationContext(), 1011, new Intent("follow"
                ), PendingIntent.FLAG_UPDATE_CURRENT));
        bigRemoteViews.setOnClickPendingIntent(R.id.close,
                PendingIntent.getBroadcast(this.getApplicationContext(), 1012,
                        new Intent("close"), PendingIntent.FLAG_UPDATE_CURRENT));

        return bigRemoteViews;
    }

    /**
     * @return 通知栏执行点击事件
     */
    private PendingIntent notificationClick() {
        Intent i = new Intent();
        i.setClass(this, MainActivity.class);
        return PendingIntent.getActivity(this.getApplicationContext(), 1001, i,
                PendingIntent.FLAG_UPDATE_CURRENT);
    }


    /**
     * 通知栏按钮响应  接收器
     */
    private class NotificationReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

            if (action.equals("play")) {//播放
                playANDpouse("play");
            } else if (action.equals("pouse")) {//暂停
                playANDpouse("pouse");
            } else if (action.equals("lastsong")) {//上一首歌
                changeSong("last");
            } else if (action.equals("nextsong")) {//一首歌
                changeSong("next");
            } else if (action.equals("follow")) {//收藏
                //bind方式启动的service不能弹出Toast
                Util.showToast(context, "收藏");
            } else if (action.equals("close")) {//关闭通知栏
                //startService方式启动才有效
                stopSelf();
            }
        }
    }

    /**
     * 点击播放/暂停
     */
    private void playANDpouse(String option) {
        if (option.equals("play")) {//点击播放
            smallremoteView.setViewVisibility(R.id.pouse, View.VISIBLE);
            smallremoteView.setViewVisibility(R.id.play, View.INVISIBLE);

            bigRemoteViews.setViewVisibility(R.id.pouse, View.VISIBLE);
            bigRemoteViews.setViewVisibility(R.id.play, View.INVISIBLE);
        } else {//点击暂停
            smallremoteView.setViewVisibility(R.id.pouse, View.INVISIBLE);
            smallremoteView.setViewVisibility(R.id.play, View.VISIBLE);

            bigRemoteViews.setViewVisibility(R.id.pouse, View.INVISIBLE);
            bigRemoteViews.setViewVisibility(R.id.play, View.VISIBLE);
        }

        notificationBuilder.setCustomContentView(smallremoteView);
        notificationBuilder.setCustomBigContentView(bigRemoteViews);
        notificationManager.notify(NOTICEID, notificationBuilder.build());
    }

    /**
     * 切换歌曲
     */
    private void changeSong(String option) {
        if (option.equals("last")) {//上一首
            switch (nowsong) {
                case 1:
                    nowsong = 3;
                    smallremoteView.setTextViewText(R.id.songname, "江南Style");
                    smallremoteView.setTextViewText(R.id.songer, "鸟叔");
                    smallremoteView.setImageViewResource(R.id.songlogo, R.drawable.jnstyle);

                    bigRemoteViews.setTextViewText(R.id.songname, "江南Style");
                    bigRemoteViews.setTextViewText(R.id.songer, "鸟叔");
                    bigRemoteViews.setImageViewResource(R.id.songlogo, R.drawable.jnstyle);
                    break;
                case 2:
                    nowsong = 1;
                    smallremoteView.setTextViewText(R.id.songname, "豆豆龙");
                    smallremoteView.setTextViewText(R.id.songer, "范晓萱");
                    smallremoteView.setImageViewResource(R.id.songlogo, R.drawable.lm);

                    bigRemoteViews.setTextViewText(R.id.songname, "豆豆龙");
                    bigRemoteViews.setTextViewText(R.id.songer, "范晓萱");
                    bigRemoteViews.setImageViewResource(R.id.songlogo, R.drawable.lm);
                    break;
                case 3:
                    nowsong = 2;
                    smallremoteView.setTextViewText(R.id.songname, "小棋童");
                    smallremoteView.setTextViewText(R.id.songer, "双笙");
                    smallremoteView.setImageViewResource(R.id.songlogo, R.drawable.xqt);

                    bigRemoteViews.setTextViewText(R.id.songname, "小棋童");
                    bigRemoteViews.setTextViewText(R.id.songer, "双笙");
                    bigRemoteViews.setImageViewResource(R.id.songlogo, R.drawable.xqt);
                    break;
                default:
                    break;
            }
        } else {//下一首
            switch (nowsong) {
                case 1:
                    nowsong = 2;
                    smallremoteView.setTextViewText(R.id.songname, "小棋童");
                    smallremoteView.setTextViewText(R.id.songer, "双笙");
                    smallremoteView.setImageViewResource(R.id.songlogo, R.drawable.xqt);

                    bigRemoteViews.setTextViewText(R.id.songname, "小棋童");
                    bigRemoteViews.setTextViewText(R.id.songer, "双笙");
                    bigRemoteViews.setImageViewResource(R.id.songlogo, R.drawable.xqt);
                    break;
                case 2:
                    nowsong = 3;
                    smallremoteView.setTextViewText(R.id.songname, "江南Style");
                    smallremoteView.setTextViewText(R.id.songer, "鸟叔");
                    smallremoteView.setImageViewResource(R.id.songlogo, R.drawable.jnstyle);

                    bigRemoteViews.setTextViewText(R.id.songname, "江南Style");
                    bigRemoteViews.setTextViewText(R.id.songer, "鸟叔");
                    bigRemoteViews.setImageViewResource(R.id.songlogo, R.drawable.jnstyle);
                    break;
                case 3:
                    nowsong = 1;
                    smallremoteView.setTextViewText(R.id.songname, "豆豆龙");
                    smallremoteView.setTextViewText(R.id.songer, "范晓萱");
                    smallremoteView.setImageViewResource(R.id.songlogo, R.drawable.lm);

                    bigRemoteViews.setTextViewText(R.id.songname, "豆豆龙");
                    bigRemoteViews.setTextViewText(R.id.songer, "范晓萱");
                    bigRemoteViews.setImageViewResource(R.id.songlogo, R.drawable.lm);
                    break;
                default:
                    break;
            }
        }
        notificationBuilder.setCustomContentView(smallremoteView);
        notificationBuilder.setCustomBigContentView(bigRemoteViews);
        notificationManager.notify(NOTICEID, notificationBuilder.build());
    }

    /**
     * service里面自定义的方法
     */
    private void methodInMyService1() {
        Util.showToast(MyService.this, "服务里的方法1执行了。。。");
    }

    /**
     * service里面自定义的方法
     */
    private void methodInMyService2() {
        Util.showToast(MyService.this, "服务里的方法2执行了。。。");
    }


    public class MyBinder extends Binder implements IMyBinder {


        /**
         * 避免activity结束时,由于service中强引用activity导致内存泄漏
         */
        private WeakReference<MainActivity> mainActivityWeakReference;
        private MyService myService;

        private MyBinder(MyService myService) {
            this.myService = myService;
        }

        public MyService getMyService() {
            return myService;
        }

        @Override
        public void setActivity(Activity activity) {
            if (activity != null && activity instanceof MainActivity) {
                mainActivityWeakReference = new WeakReference<>((MainActivity) activity);
            }
        }

        @Override
        public void callmethodOfService1() {
            methodInMyService1();
        }

        @Override
        public void callmethodOfService2() {
            methodInMyService2();
        }
    }

}